// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

/*!
\file
\brief PI Calculation, MPI Demo program
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <mpi.h>

int main(int argc, char *argv[])
{
    int n, myid, numprocs, i;
    double PI25DT = 3.141592653589793238462643;
    double mypi, pi, h, sum, x;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
	
	n = numprocs;
	
	if (n > 0) {
		MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
	
		h   = 1.0 / (double) n;
		sum = 0.0;
		for (i = myid + 1; i <= n; i += numprocs) {
			x = h * ((double)i - 0.5);
			sum += (4.0 / (1.0 + x*x));
		}
		mypi = h * sum;
		MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

		if (myid == 0) {
			time_t rawtime;
			struct tm * t;
			
			time (&rawtime);
			t = localtime(&rawtime);

			printf("PI calculated to be approximately %.16f, Error is %.16f\nDated: %s", pi, fabs(pi - PI25DT), asctime(t));			
		}
	}
	
	MPI_Finalize();

    return 0;
}